home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 1 / Meeting Pearls Vol 1 (1994).iso / installed_progs / gfx / pbm / source / ppmchange.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-17  |  4.5 KB  |  155 lines

  1. /* ppmchange.c - change a given color to another
  2. **
  3. ** Copyright (C) 1991 by Wilson H. Bent, Jr.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. **
  12. ** Modified by Alberto Accomazzi (alberto@cfa.harvard.edu).
  13. **     28 Jan 94 -  Added support for multiple color substitution.
  14. ** Modified by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
  15. **     17 Jun 94 -  fixed maxval bug, rework to use hash tables, "-file" and "-other" options
  16. */
  17.  
  18. #include "ppm.h"
  19. #include "ppmcmap.h"
  20.  
  21. #define TCOLS   1024
  22.  
  23.  
  24. static void add_colorchange ARGS((char *name1, char *name2, pixval maxval,
  25.                                   colorhash_table hashtable, pixel *changerow, int *idxP));
  26.  
  27.  
  28. int
  29. main( argc, argv )
  30.     int argc;
  31.     char* argv[];
  32. {
  33.     FILE* ifp;
  34.     int argn, format, first, last;
  35.     register int row, col, i;
  36.     int rows, cols, ncolors, maxcolors, changes;
  37.     pixel *prow, *new, pix;
  38.     colorhash_table cht;
  39.     pixval maxval;
  40.     char *chfile = NULL;
  41.     char *othercol = NULL;
  42.     char *usage = "[-file <changesfile>] [-other <color>] [<oldcolor> <newcolor> [...]] [ppmfile]";
  43.  
  44.     ppm_init( &argc, argv );
  45.  
  46.     argn = 1;
  47.     while( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
  48.         if( pm_keymatch(argv[argn], "-file", 2) ) {
  49.             if( ++argn >= argc ) pm_usage(usage);
  50.             chfile = argv[argn];
  51.         }
  52.         else
  53.         if( pm_keymatch(argv[argn], "-other", 2) ) {
  54.             if( ++argn >= argc ) pm_usage(usage);
  55.             othercol = argv[argn];
  56.         }
  57.         else
  58.             pm_usage(usage);
  59.         ++argn;
  60.     }
  61.  
  62.     first = argn;
  63.     if( argn < argc ) {
  64.         last = argc-1;
  65.         if( !odd(last-first) ) last--;
  66.         argn = last+1;
  67.     }
  68.     ncolors = (argn-first)/2;       /* (last-first+1)/2 */
  69.  
  70.     if( argn < argc ) {
  71.         ifp = pm_openr(argv[argn]);
  72.         ++argn;
  73.     }
  74.     else
  75.         ifp = stdin;
  76.     if( argn != argc )
  77.         pm_usage(usage);
  78.  
  79.     ppm_pbmmaxval = PPM_MAXMAXVAL;
  80.     ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
  81.     ppm_writeppminit( stdout, cols, rows, maxval, 0 );
  82.     prow = ppm_allocrow( cols );
  83.  
  84.     maxcolors = ncolors + TCOLS;
  85.     cht = ppm_alloccolorhash();
  86.     new = ppm_allocrow(maxcolors);
  87.     changes = 0;
  88.     if( chfile ) {
  89.         FILE *fp;
  90.         char buf1[256], buf2[256];
  91.         if( fp = fopen(chfile, "r") ) {
  92.             while( fscanf(fp, "%s %s", buf1, buf2) == 2 ) {
  93.                 if( changes == TCOLS ) {
  94.                     pm_message("too many color changes in file (max %d) - ignoring extra", TCOLS);
  95.                     break;
  96.                 }
  97.                 add_colorchange(buf1, buf2, maxval, cht, new, &changes);
  98.             }
  99.             fclose(fp);
  100.         }
  101.         else
  102.             pm_error("cannot open changes file");
  103.     }
  104.     for( i = 0; i < ncolors; i++, first += 2 )
  105.         add_colorchange(argv[first], argv[first+1], maxval, cht, new, &changes);
  106.     if( othercol )
  107.         pix = ppm_parsecolor(othercol, maxval);
  108.  
  109.     /* Scan for the desired color */
  110.     for ( row = 0; row < rows; ++row ) {
  111.         ppm_readppmrow( ifp, prow, cols, maxval, format );
  112.         for ( col = 0; col < cols; ++col ) {
  113.             i = ppm_lookupcolor(cht, &prow[col]);
  114.             if( i >= 0 )
  115.                 prow[col] = new[i];
  116.                 /*PPM_ASSIGN(prow[col], PPM_GETR(new[i]), PPM_GETG(new[i]), PPM_GETB(new[i]));*/
  117.             else
  118.             if( othercol )
  119.                 prow[col] = pix;
  120.                 /*PPM_ASSIGN(prow[col], PPM_GETR(pix), PPM_GETG(pix), PPM_GETB(pix));*/
  121.         }
  122.         ppm_writeppmrow( stdout, prow, cols, maxval, 0 );
  123.     }
  124.     pm_close( ifp );
  125.  
  126.     exit( 0 );
  127. }
  128.  
  129.  
  130. static void
  131. add_colorchange(name1, name2, maxval, hashtable, changerow, idxP)
  132.     char *name1, *name2;
  133.     pixval maxval;
  134.     colorhash_table hashtable;
  135.     pixel *changerow;
  136.     int *idxP;
  137. {
  138.     int i;
  139.     pixel p1, p2;
  140.  
  141.     p1 = ppm_parsecolor(name1, maxval);
  142.     p2 = ppm_parsecolor(name2, maxval);
  143.  
  144.     i = ppm_lookupcolor(hashtable, &p1);
  145.     if( i >= 0 )
  146.         changerow[i] = p2;
  147.     else {
  148.         if( ppm_addtocolorhash(hashtable, &p1, *idxP) < 0 )
  149.             pm_error("cannot add to color hash table - out of memory?");
  150.         changerow[*idxP] = p2;
  151.         (*idxP)++;
  152.     }
  153. }
  154.  
  155.